#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'wshu'
__version__ = '1.0'
"""
    ***********************************
    *  @filename : ASSETS.py
    *  @Author : wshu
    *  @CodeDate : 2020/6/13 9:57
    *  @Software : PyCharm
    ***********************************
    资产模型
"""
from . import BaseModel
from sqlalchemy.sql import expression
from sqlalchemy.orm import relationship, backref
from sqlalchemy import (Column, ForeignKey, Table)
from sqlalchemy.types import (String, Integer, Boolean, Text, DateTime, LargeBinary)

from .RBAC import User
from sqlalchemy_utils.types.choice import ChoiceType
from core.comm.utils import timezone

ASSET_STATUS = (
    ('0', '在线'),
    ('1', '下线'),
    ('2', '未知'),
    ('3', '故障'),
    ('4', '备用k'),
)
ASSET_TYPE = (
    ('SERVER', '服务器'),
    ('NETWORK_DEVICE', '网络设备'),
    ('STORAGE_DEVICE', '存储设备'),
    ('SECURITY_DEVICE', '安全设备'),
    ('SOFTWARE', '软件资产'),
)

class Asset(BaseModel):
    """
    资产表
    """
    __tablename__ = 'asset'

    asset_id = Column(String(50), unique=True, nullable=False, comment='系统编号')
    asset_out_id = Column(String(50), nullable=False, comment='资产编号')
    asset_type = Column(String(50), ChoiceType(ASSET_TYPE), default='SERVER', comment='资产类型')
    asset_name = Column(String(100), comment='资产名称')
    asset_key = Column(String(50), unique=True, comment='唯一标记')
    asset_description = Column(Text, nullable=True, comment='资产介绍')
    asset_score = Column(Integer, default='0', comment='重要性估值')
    asset_status = Column(String(50), ChoiceType(ASSET_STATUS), default='0', comment='资产状态')
    asset_check = Column(Boolean, server_default=expression.false(), nullable=False, comment='是否检查')
    asset_inuse = Column(Boolean, server_default=expression.false(), nullable=False, comment='是否认领')
    create_at = Column(DateTime, default=timezone.now, comment='添加时间')
    update_at = Column(DateTime, default=timezone.now, comment='更新时间')

    # web资产关联
    internet = relationship('InternetInfo', backref=backref('asset', uselist=False))
    # 安全设备资产关联
    security = relationship('SecurityDevice', backref=backref('asset', uselist=False))
    # 网络设备资产关联
    network = relationship('NetworkDevice', backref=backref('asset', uselist=False))

    def __str__(self):
        return self.asset_key

class AssetType(BaseModel):
    """
    V1.0 版本资产类型，默认会加载系统资产类型
    1.1之后会做更改
    """
    __tablename__ = 'asset_type'

    name = Column(String(50), comment='资产分类')
    description = Column(Text, comment='资产简介')
    parent = Column(Integer, ForeignKey('asset_type.id', ondelete='CASCADE'), comment='父级')

    def __str__(self):
        return self.name

class AssetTypeInfo(BaseModel):
    __tablename__ = 'asset_type_info'

    key = Column(String(50), unique=True, nullable=False, comment='属性标识')
    name = Column(String(30), comment='资产属性')

    def __str__(self):
        return self.name

# WEB资产
WEB_LANGUAGE = (
    ('C/C++', 'C/C++'),
    ('C#', 'C#'),
    ('Ruby', 'Ruby'),
    ('JAVA', 'JAVA'),
    ('ASP.NET', 'ASP.NET'),
    ('JSP', 'JSP'),
    ('PHP', 'PHP'),
    ('Perl', 'Perl'),
    ('Python', 'Python'),
    ('VB.NET', 'VB.NET'),
    ('Other', 'Other'),
)
# WEB资产类型
WEB_STATUS = (
    ('0', '测试系统'),
    ('1', '演示系统'),
    ('3', '内部使用'),
    ('4', '商用系统'),
)

class InternetInfo(BaseModel):
    """
    web
    """
    __tablename__ = 'internet_info'

    middleware = Column(String(50), nullable=False, comment='中间件')
    middleware_version = Column(String(50), nullable=False, comment='版本')
    is_out = Column(Boolean, server_default=expression.false(), nullable=False, comment='是否发布')
    out_key = Column(String(50), nullable=False, comment='域名')
    web_status = Column(String(50), ChoiceType(WEB_STATUS), default='测试系统', comment='状态说明')
    language = Column(String(50), ChoiceType(WEB_LANGUAGE), nullable=False, comment='开发语言')
    language_version = Column(String(50), nullable=True, comment='语言版本')
    web_framwork = Column(String(50), nullable=True, comment='开发框架')
    web_framwork_version = Column(String(50), nullable=True, comment='开发框架版本')
    start_at = Column(DateTime, server_default=timezone.now, comment='开始时间')
    update_at = Column(DateTime, server_default=timezone.now, comment='更新时间')

    asset = Column(Integer, ForeignKey('asset.id', ondelete='CASCADE'))

    def __str__(self):
        return self.asset

class PortInfo(BaseModel):
    """
    端口
    """
    __tablename__ = 'idc'

    port = Column(String(50), comment='开放端口')
    name = Column(String(50), nullable=True, comment='服务名称')
    product = Column(String(100), nullable=True, comment='产品信息')
    version = Column(String(50), nullable=True, comment='应用版本')
    port_info = Column(Text, nullable=True, comment='端口介绍')
    start_at = Column(DateTime, server_default=timezone.now, comment='开始时间')
    update_at = Column(DateTime, server_default=timezone.now, comment='更新时间')

    asset = Column(Integer, ForeignKey('asset.id', ondelete='CASCADE'))

    def __str__(self):
        return self.port

class Files(BaseModel):
    """
    附件
    """
    name = Column(String(50), comment='附件名称')
    file = Column(LargeBinary, comment='附件内容')
    file_info = Column(Text, nullable=True, comment='附件说明')
    update_at = Column(DateTime, default=timezone.now, comment='更新时间')

    asset = Column(Integer, ForeignKey('asset.id', ondelete='CASCADE'))

    def __str__(self):
        return self.name


# ==========
# 以下为V1.1系统升级新版本后的扩展功能， 作为预留
# ==========
# 安全资产类型统计
'''
SECURITY_TYPE = (
    ('0', '防火墙'),
    ('1', '入侵检测设备'),
    ('3', '互联网网关'),
    ('4', '运维审计系统'),
)
class SecurityDevice(BaseModel):
    """
    安全设备
    """
    __tablename__ = 'security_device'

    subasset_type = Column(String(50), ChoiceType(SECURITY_TYPE), default='0', comment='安全设备类型')
    model = Column(String(128), default='未知型号', comment='安全设备型号')
    asset = Column(Integer, ForeignKey('asset.id', ondelete='CASCADE'))

    def __str__(self):
        return self.asset

NETWORK_TYPE = (
    ('0', '路由器'),
    ('1', '交换机'),
    ('3', '负载均衡'),
    ('4', 'VPN设备'),
)
class NetworkDevice(BaseModel):
    """
    网络设备
    """
    __tablename__ = 'network_device'

    subasset_type = Column(String(50), ChoiceType(NETWORK_TYPE), default='0', comment='网络设备类型')
    vlan_ip = Column(String(50), nullable=True, comment='VLanIP')
    intranet_ip = Column(String(50), nullable=True, comment='内网IP')

    model = Column(String(128), default='未知型号', comment='网络设备型号')
    detail = Column(Text, nullable=True, comment='详细配置')

    asset = Column(Integer, ForeignKey('asset.id', ondelete='CASCADE'))

    def __str__(self):
        return self.asset

# 付费软件类型
PAYWARE_TYPE = (
    ('0', '操作系统'),
    ('1', '办公开发'),
    ('3', '业务软件'),
)
class Payware(BaseModel):
    """
    付费软件
    """
    __tablename__ = 'payware'

    subasset_type = Column(String(50), ChoiceType(PAYWARE_TYPE), default='0', comment='软件类型')
    license_num = Column(Integer, default=1, comment='授权数量')
    version_info = Column(String(128), unique=True, comment='软件/系统版本信息')

    def __str__(self):
        return self.subasset_type

class Idc(BaseModel):
    """
    机房
    """
    __tablename__ = 'idc'

    title = Column(String(50), unique=True, comment='机房名称')
    explain = Column(Text, nullable=True, comment='备注说明')

    def __str__(self):
        return self.title

class Manufacturer(BaseModel):
    """
    厂商
    """
    __tablename__ = 'manufacturer'

    title = Column(String(50), unique=True, comment='厂商名称')
    telphone = Column(String(50), nullable=True, comment='服务电话')
    explain = Column(Text, nullable=True, comment='备注说明')

    def __str__(self):
        return self.title
        
'''
